package com.wlc.springdemo.service.impl;

import com.wlc.springdemo.dao.BookStoreMapper;
import com.wlc.springdemo.po.BookStore;
import com.wlc.springdemo.po.UserInfo;
import com.wlc.springdemo.service.BookStoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 王立朝
 * @date 2022/11/23
 * @description:
 */
@Service
@Slf4j
public class BookStoreServiceImpl implements BookStoreService {

    @Resource
    private BookStoreMapper bookStoreMapper;
    /**
     * 查询所有库存
     *
     * @return
     */
    @Override
    public List<BookStore> getAllBookStore() {
        List<BookStore> bookStoreList = bookStoreMapper.getAllBookStore();
        return bookStoreList;
    }

    /**
     * 减库存
     *
     * @param
     */


    /*
        Propagation.REQUIRED:  支持当前事务，如果不存在，则创建新事务;
                验证结果： 图书库存没有减少
    */
    //@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)

    /*
        Propagation.REQUIRES_NEW:  创建一个新事务，如果存在，则挂起当前事务。
            验证结果： 图书库存减少了，一个减少了，一个没有减少
     */
    //@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)

    /*
       Propagation.SUPPORTS: 支持当前事务，如果不存在，则以非事务方式执行；
                验证结果： 图书库存没有减少，和 Propagation.REQUIRED  结果一致
     */
    //@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)

    /*
      Propagation.NOT_SUPPORTED: 非事务性执行，如果当前事务存在，则挂起当前事务。
            验证结果：图书库存减少了，一个减少了，一个没有减少，和  Propagation.REQUIRES_NEW 结果一致

      */
    //@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.NOT_SUPPORTED,rollbackFor = Exception.class)


    /*
     Propagation.NEVER  以非事务方式执行，如果存在事务，则抛出异常
     验证结果：  抛出异常
         Servlet.service() for servlet [dispatcherServlet] in context with path []
           threw exception [Request processing failed;
           nested exception is org.springframework.transaction.IllegalTransactionStateException:(非法事务异常)
            Existing transaction found for transaction marked with propagation 'never'] with root cause
     */
    //@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.NEVER,rollbackFor = Exception.class)


    /*
       Propagation.NESTED  ：如果当前事务存在，则在嵌套事务中执行，否则行为类似REQUIRED。
       验证结果：
            图书库存没有减少  ，和 Propagation.REQUIRED  结果一致
     */
    //@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.NESTED,rollbackFor = Exception.class)


    /*
       MANDATORY : 支持当前事务，如果不存在则抛出异常。
        验证结果：
           UserInfoServiceImpl.buyBook() 存在事务的情况下， 图书库存没有减少； 和 Propagation.REQUIRED  结果一致
           UserInfoServiceImpl.buyBook() 不存在事务的情况下  ,抛出异常
            Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
             [Request processing failed; nested exception is
                org.springframework.transaction.IllegalTransactionStateException:
                No existing transaction found for transaction marked with propagation 'mandatory'] with root cause
     */
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.MANDATORY,rollbackFor = Exception.class)
    @Override
    public int lessStock(BookStore bookStore, UserInfo userInfo) {

            log.info("=====>减库存操作");
            int total = bookStore.getTotal();
            int id = bookStore.getId();
            int price = bookStore.getPrice();

            int balance = userInfo.getAccount() - price;
            log.info("====》账户余额为: {}",balance);
            if(balance < 0){
                log.warn("=====>价格不够，无法购买");
                // 如果差额不够，抛异常
                throw new RuntimeException("价格不够，无法购买");
            }

            log.info("======》开始购买图书");
            // 减库存
            int result = bookStoreMapper.lessStock(id,total-1);
            // 账户金额减少
            userInfo.setAccount(balance);

            return result;

    }
}
